/**
 * @name: 将html 页面转为pdf 格式
 * @param {*} Dom：需要导出的dom
 * @param {*} title：导出pdf名称
 * @param {*} isEven:是否导出导出多页，允许多页，但是可能很丑
 * @param {*} classTimes:添加的节点数组，成功后需要被删除掉
 * @param {*} failCallback：导出失败回调
 */
import html2Canvas from "html2canvas";
import JsPDF from "jspdf";
export function html2pdf(targetDom, title, isEven, classTimes, failCallback) {
  // let cloneDom = targetDom.cloneNode(true) // clone会导致echarts失效，样式失效
  // cloneDom.style.width = targetDom.scrollWidth + 'px'
  // cloneDom.style.height = targetDom.scrollHeight + 'px'
  // cloneDom.style.background = '#FFFFFF'
  // document.body.appendChild(cloneDom)
  return new Promise((resolve, reject) => {
    html2Canvas(targetDom, {
      allowTaint: true,
      useCORS: true,
      scale: 1.4, // 提升画面质量，但是会增加文件大小
      imageTimeout: 0, // 图片加载延迟，默认延迟为0，单位毫秒
      height: targetDom.scrollHeight, // canvas的高度设定
      width: targetDom.scrollWidth // canvas的宽度设定
      // dpi: window.devicePixelRatio * scale, // 将分辨率提高到特定的DPI
    })
      .then(function(canvas) {
        // document.body.removeChild(cloneDom)
        // 页面还原，删除节点
        if (classTimes && classTimes.length) {
          for (let i = 0; i < classTimes.length; i++) {
            let par = classTimes[i].parentNode;
            par && par.removeChild(classTimes[i]);
          }
          classTimes = [];
        }
        let contentWidth = canvas.width;
        let contentHeight = canvas.height;
        // let pageHeight = (contentWidth / 592.28) * 841.89;
        // let leftHeight = contentHeight;
        let position = 0;
        let imgWidth = 595.28;
        let imgHeight = (592.28 / contentWidth) * contentHeight;
        let pageData = canvas.toDataURL("image/jpeg", 1.0);
        // setImg(pageData)
        // download(pageData, title + '.png')
        let url = downloadBlobUrl(pageData, title + ".png");

        // 以下转成pdf
        // let PDF = isEven ? new JsPDF('', 'pt', 'a4') : new JsPDF('', 'px', [imgHeight, imgWidth]) // A4 纵向 : 指定宽高

        // if (leftHeight < pageHeight) {
        //   PDF.addImage(pageData, 'JPEG', 0, 0, imgWidth, imgHeight)
        // } else {
        //   if (isEven) {
        //     while (leftHeight > 0) {
        //       PDF.addImage(pageData, 'JPEG', 0, position, imgWidth, imgHeight)
        //       leftHeight -= pageHeight
        //       position -= 841.89
        //       if (leftHeight > 0) {
        //         PDF.addPage()
        //       }
        //     }
        //   } else {
        //     PDF.addImage(pageData, 'JPEG', 0, 0, imgWidth, imgHeight)

        //   }

        // }
        // PDF.save(title + '.pdf')
        // console.log('success')
        // base64转成文件
        // let buffer = pdf.output('datauristring')
        // let myfile = dataURLtoFile(buffer, name)
        // failCallback(myfile)
        resolve(url);
      })
      .catch(err => {
        failCallback instanceof Function && failCallback();
        console.error("导出pdf报错", err);
        if (classTimes && classTimes.length) {
          for (let i = 0; i < classTimes.length; i++) {
            let par = classTimes[i].parentNode;
            par && par.removeChild(classTimes[i]);
          }
          classTimes = [];
        }
        reject(err);
      });
  });
}

/**
 * @name: 遍历子节点中class为target-node-item的元素,计算出target-node-item的元素距离顶部的偏移量，如果(元素1距离上方或上层控件的位置+元素1本身的高度小于A4纸的高度，并且下一个元素距离上方或上层控件的位置+下一个元素本身的高度大于A4纸的高度)，则在两个园中中间插入一个空白块，空白的高度通过计算，为a4纸的高度减去元素1的offsetTop + offsetHeight，我们可以在计算出的高度上再加一个固定高度，避免下一页内容挨着分割线
 * @param {*} nodes
 * @param {*} index
 * @param {*} pageHeight
 */
export function isSplit(nodes, index, pageHeight) {
  if (
    nodes[index].offsetTop + nodes[index].offsetHeight < pageHeight &&
    nodes[index + 1] &&
    nodes[index + 1].offsetTop + nodes[index + 1].offsetHeight > pageHeight
  ) {
    return true;
  }
  return false;
}

/**
 * @name: 设置target-node-item，以判断转为pdf的图层不能被隔断
 * @param {*} id
 * @param {*} name
 * @param {*} isEven :是否显示多页
 * @param {*} targetClass :指定不能隔断的class，isEven为true，则必填
 */
export function outPutPdfFn(id, name, isEven, targetClass) {
  const A4_WIDTH = 592.28;
  const A4_HEIGHT = 841.89;

  // this.$nextTick(async () => {
  // let target = vm.$refs.targetDom
  let target = document.querySelector(id);
  let pageHeight = (target.scrollWidth / A4_WIDTH) * A4_HEIGHT;
  let classTime,
    classTimes = [];
  if (isEven) {
    let lableListID = target.getElementsByClassName(targetClass);
    classTime = "export_" + new Date().getTime();
    for (let i = 0; i < lableListID.length; i++) {
      let multiple = Math.ceil(
        (lableListID[i].offsetTop + lableListID[i].offsetHeight) / pageHeight
      );

      if (isSplit(lableListID, i, multiple * pageHeight)) {
        let divParent = lableListID[i].parentNode; // 获取该div的父节点

        let newNode = document.createElement("div");
        newNode.style.background = "#ffffff";
        // newNode.style.display = 'none'
        let _H =
          multiple * pageHeight -
          (lableListID[i].offsetTop + lableListID[i].offsetHeight);
        newNode.style.height = _H + 50 + "px";
        let next = lableListID[i].nextSibling; // 获取div的下一个兄弟节点
        newNode.setAttribute("class", classTime);
        // 判断兄弟节点是否存在
        if (next) {
          // 存在则将新节点插入到div的下一个兄弟节点之前，即div之后
          divParent.insertBefore(newNode, next);
        } else {
          // 不存在则直接添加到最后,appendChild默认添加到divParent的最后
          divParent.appendChild(newNode);
        }
        classTimes.push(newNode);
      }
    }
  }

  return html2pdf(target, name, isEven, classTimes);
  // })
}

// 深拷贝对象 - 导出pdf样式不一致时，克隆html元素重新导出
export function deepClone(obj) {
  const _toString = Object.prototype.toString;

  // null, undefined, non-object, function
  if (!obj || typeof obj !== "object") {
    return obj;
  }

  // DOM Node
  if (obj.nodeType && "cloneNode" in obj) {
    return obj.cloneNode(true);
  }

  // Date
  if (_toString.call(obj) === "[object Date]") {
    return new Date(obj.getTime());
  }

  // RegExp
  if (_toString.call(obj) === "[object RegExp]") {
    const flags = [];
    if (obj.global) {
      flags.push("g");
    }
    if (obj.multiline) {
      flags.push("m");
    }
    if (obj.ignoreCase) {
      flags.push("i");
    }

    return new RegExp(obj.source, flags.join(""));
  }

  const result = Array.isArray(obj)
    ? []
    : obj.constructor
    ? new obj.constructor()
    : {};

  for (const key in obj) {
    result[key] = deepClone(obj[key]);
  }

  return result;
}

/**
 * @name: Blob 类型文件下载
 * @param {*} blobUrl
 * @param {*} name
 */
export function downloadBlobUrl(blobUrl, name, type) {
  let lastIndex = name.lastIndexOf(".");
  let startStr = name.substring(0, lastIndex);
  let endStr = name.substring(lastIndex);

  const link = document.createElement("a");
  // const blob = new Blob([blobUrl], type);
  let blob = base64ToBlob(blobUrl); //new Blob([content]); // 含有'base64文字'
  console.log(URL.createObjectURL(blob));
  return window.URL.createObjectURL(blob);
  link.setAttribute("href", window.URL.createObjectURL(blob));
  link.setAttribute("download", startStr + endStr);
  link.style.visibility = "hidden";
  // document.body.appendChild(link);
  link.click();
  // document.body.removeChild(link);
}

//base64转blob
function base64ToBlob(code) {
  let parts = code.split(";base64,");
  let contentType = parts[0].split(":")[1];
  let raw = window.atob(parts[1]);
  let rawLength = raw.length;

  let uInt8Array = new Uint8Array(rawLength);

  for (let i = 0; i < rawLength; ++i) {
    uInt8Array[i] = raw.charCodeAt(i);
  }
  return new Blob([uInt8Array], {
    type: contentType
  });
}
